using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Shape;
using GameCamera;
using Light;

namespace CGEx2
{

  public class Game1 : Microsoft.Xna.Framework.Game
  {
    GraphicsDeviceManager graphics;
    Camera mainCamera;
    Vector3[] lights;
    List<IShape> shapes;
    KeyboardState oldState;
    LightPoint light;
    IShape gouraudShape, flatShape, phongShape;

    public Game1()
    {
      graphics = new GraphicsDeviceManager(this);
      graphics.PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
      graphics.PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
      graphics.IsFullScreen = true;
      Content.RootDirectory = "Content";
    }

    protected override void Initialize()
    {
      oldState = Keyboard.GetState();
      Content.RootDirectory = "Content";
      mainCamera = new Camera(true, new Vector3(0.0f, 0.0f, 50.0f), GraphicsDevice.Viewport);
      lights = new Vector3[3];
      shapes = new List<IShape>();
      base.Initialize();
    }

    protected override void LoadContent()
    {
      Effect lightingEffect = Content.Load<Effect>("Lighting");
      light = new LightPoint(mainCamera, lightingEffect, Color.White.ToVector4(), 0.5f, 
        new Vector3(0.0f, 30.0f, 60.0f), Color.White.ToVector4());
      IShape phongSphere = new Sphere(new Vector3(0.0f, 0.0f, 0.0f), 10.0f, graphics.GraphicsDevice, lightingEffect, Color.White, 40);
      IShape gouraudSphere = new Sphere(new Vector3(0.0f, 0.0f, 0.0f), 10.0f, graphics.GraphicsDevice, lightingEffect, Color.White, 40);
      IShape flatSphere = new SphereTriple(new Vector3(0.0f, 0.0f, 0.0f), 10.0f, graphics.GraphicsDevice, lightingEffect, Color.White, 40);
      shapes.Add(phongSphere);
      shapes.Add(gouraudSphere);
      shapes.Add(flatSphere);
      phongShape = phongSphere;
      gouraudShape = gouraudSphere;
      flatShape = flatSphere;
      gouraudShape.Visible = false;
      phongShape.Visible = false;
      foreach (var shape in shapes)
      {
        shape.Effect = light.LightingEffect;
        shape.Effect.CurrentTechnique = light.LightingEffect.Techniques["SpecularTechnique"];
      }
    }

    private void InputDetection()
    {
      KeyboardState keyboardState = Keyboard.GetState();
      if (keyboardState.IsKeyDown(Keys.Escape))
        this.Exit();
      if (keyboardState.IsKeyDown(Keys.F1))
      {
        foreach (var shape in shapes)
          shape.FillMode = FillMode.WireFrame;
      }
      if (keyboardState.IsKeyDown(Keys.F2))
      {
        foreach (var shape in shapes)
          shape.FillMode = FillMode.Solid;
      }
      if (keyboardState.IsKeyDown(Keys.F3))
      {
        foreach (var shape in shapes)
        {
          if (shape == flatShape)
            shape.Visible = true;
          else
            shape.Visible = false;
        }
      }
      if (keyboardState.IsKeyDown(Keys.F4))
      {
        foreach (var shape in shapes)
        {
          shape.Effect.CurrentTechnique = light.LightingEffect.Techniques["GouraudTechnique"];
          if (shape == gouraudShape)
            shape.Visible = true;
          else
            shape.Visible = false;
        }

      }
      if (keyboardState.IsKeyDown(Keys.F5))
      {
        foreach (var shape in shapes)
        {
          shape.Effect.CurrentTechnique = light.LightingEffect.Techniques["SpecularTechnique"];
          if (shape == phongShape)
            shape.Visible = true;
          else
            shape.Visible = false;
        }

      }
      if (keyboardState.IsKeyDown(Keys.R) && !oldState.IsKeyDown(Keys.R))
      {
        foreach (var shape in shapes)
        {
          shape.Rotate = !shape.Rotate;
        }
      }
      if (keyboardState.IsKeyDown(Keys.L) && !oldState.IsKeyDown(Keys.L))
      {
        light.Rotate = !light.Rotate;
      }
      oldState = keyboardState;
    }

    protected override void Update(GameTime gameTime)
    {
      InputDetection();
      mainCamera.Update();
      light.Update();
      base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
      GraphicsDevice.Viewport = mainCamera.viewport;
      GraphicsDevice.Clear(Color.Black);
      drawAll(mainCamera);
      base.Draw(gameTime);
    }

    private void drawAll(Camera camera)
    {
      foreach (var shape in shapes)
        shape.drawShape(mainCamera);
    }
  }
}
